import java.io.*;  
import java.net.ServerSocket;  
import java.net.Socket;   

public class SimpleHttpServer {  
    static String webPath = ".";    // Web文件所在目录
    static int port = 8085;  // 默认端口
    public static void main(String[] args) throws IOException {  
        // 处理参数
        if(args.length != 0){   // 如果有参数
            System.out.println("参数1:"+args[0]); 
            System.out.println("参数2:"+args[1]); 
            if (Character.isDigit(args[0].charAt(0))) { // 传入的第一个值是否数值
                port = Integer.parseInt(args[0]);
            }else if(args.length == 2){
                webPath = args[1];
            }else{
                if(args[0].equals("help") || args[0].equals("--help") || args[0].equals("-h")){
                    System.out.println("传入的第一个参数为端口号,默认8085。"); 
                    System.out.println("传入的第二个参数为web目录,默认本程序运行目录。"); 
                }
            }
        }
        // 创建监听
        ServerSocket serverSocket = new ServerSocket(port);  
        System.out.println("web目录:" + webPath); 
        System.out.println("监听: http://localhost:" + port);  
        
        while (true) {  
            // 处理完再次监听
            Socket clientSocket = serverSocket.accept();  
            // 为每个客户端请求创建一个新的线程  
            new Thread(() -> handleClientRequest(clientSocket,webPath)).start();  
        }  
    }   
    // http主处理
    private static void handleClientRequest(Socket clientSocket,String webRootPath) {  

        BufferedReader in = null;  
        PrintWriter out = null;  
        try {  
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));  
            out = new PrintWriter(clientSocket.getOutputStream(), true);  
  
            // 读取HTTP请求的第一行（请求行）  
            String requestLine = in.readLine();  
            //System.out.println("客户获取: " + requestLine);
            if(requestLine == null) return;                     // 如果返回null 就直接返回
            // if(!requestLine.contains(String.valueOf(" "))) return;  // 如果没有空格 不符合数据格式,直接返回
            String[] inargs = requestLine.split("\\s+"); // 使用正则表达式分隔空格
/*             for (String word : inargs) {
                System.out.println(word);
            } */
            String response;    // 返回客户端文本
            // 这里简单处理GET请求，并返回固定的响应  
            if (inargs[0].equals("GET")) {              // GET 方式
                String urlstr = inargs[1];          // 文件名和参数字符串
                String filestr = urlstr;         // 文件
                String pargs = "";           // ? 后的参数
                if (urlstr.equals("/")) filestr = "/index.html";    // 如果是 / 转化为index.html主页
                filestr = webRootPath + filestr;                    // 加上 路径
                System.out.println("获取url：" + filestr);
                if(filestr.contains(String.valueOf("?"))){       // 如果有问号 就是传入参数
                    String[] _upa = filestr.split("\\?");        // 分割出路径和参数
                    filestr = _upa[0];      // 路径
                    pargs = _upa[1];        // 参数
                    System.out.println("获取文件：" + filestr);
                    System.out.println("参数字串：" + pargs);

                    if(pargs.contains(String.valueOf("&"))){       // 如果有与号 就是多个参数
                        String[] _upaa = pargs.split("\\&");        // 分割出参数
                        for (String word : _upaa) {                 // 遍历参数
                            System.out.println(word);
                            if(pargs.contains(String.valueOf("="))){       // 如果有与号 就是多个参数
                                String[] _upaaa = word.split("=");        // 分割出参数
                                System.out.println(_upaaa[0] + " : "+_upaaa[1] );   // 关键字 和 值
                            }else{
                                // 没有等于号的参数
                            }
                        }
                    }else{
                        // 只有一个参数的url
                    }
                }
                // text/javascript text/html text/css
                // image/png image/gif image/x-icon
                if(FS.exist(filestr)){                // 判断URL 判断文件是否存在
                    response = "HTTP/1.1 200 OK\r\n"  
                        + "Content-Type: text/html\r\n"  
                        + "\r\n"  
                    //    + "<html><body><h1>Hello, World!</h1></body></html>";  
                    +FS.Read(filestr);
                }else{                              // 文件不存在
                    response = "HTTP/1.1 404 Not Found\r\n"  
                        + "Content-Type: text/plain\r\n"  
                        + "\r\n"  
                        + "页面 "+inargs[1] + "并不存在.\r\n"
                        + "No page is registered at '"+inargs[1]+"'.";  
                }
            }else if(inargs[0].equals("POST")){         // POST 方式
                StringBuilder requestBody = new StringBuilder();
                StringBuilder requestHead = new StringBuilder();
                    // 读取请求体 全部
                    requestHead.append(requestLine+"\r\n");
                    String iL = "0";
                    while (iL.length() != 0) {    // 直到读完头
                        iL = in.readLine();
                        requestHead.append(iL+"\r\n");
                        // System.out.println("获取数据: \n" + iL+" 数据长度:"+iL.length());
                    }
                    while (in.ready()) {    // 直到body读完
                        char ir = (char) in.read();
                        requestBody.append(ir);
                        // System.out.println("获取数据: \n" + ir);
                    }
                    System.out.println("接收到的 HEAD 数据: \n" + requestHead.toString());
                    System.out.println("接收到的 POST 数据: \n" + requestBody.toString());
                response = "HTTP/1.1 200 OK\r\n"  
                    + "Content-Type: application/json\r\n"  
                    + "\r\n"
                    +"{\"key\":\"ok\",\"code\":\"200\"}";           // 返回的json数据
            }else{
                response = "HTTP/1.1 405 Method Not Allowed\r\n"  
                        + "Content-Type: text/plain\r\n"  
                        + "\r\n"  
                        + "Method Not Allowed"; 
            }
            out.println(response); 
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if (in != null) in.close();  
                if (out != null) out.close();  
                clientSocket.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}
// 文件操作对象
class FS {
    // 判断文件是否存在
    public static Boolean exist(String filepath) {
        File file = new File(filepath);
        return file.exists();
    }
    // 读取文件，filepath 为文件路径及名字。比如"index.html"，返回文件文本
    public static String Read(String filepath) {
        File file = new File(filepath);
        String reString = "";

        try (FileInputStream fis = new FileInputStream(file);
             InputStreamReader isr = new InputStreamReader(fis);
             BufferedReader br = new BufferedReader(isr)) {
             
            String line;
            while ((line = br.readLine()) != null) {
                //System.out.println(line);     // 逐行显示
                reString=reString+line+"\r\n";
            };
            
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reString;
    }
}